--英雄系统功能
--#include "data\config\hero\NewHeroConfig.lua" once

--[[
每日处理
]]
function OnHeroDailyProc( sysarg )
	local sVar = Actor.getStaticVar(sysarg)
	sVar.heroBattleTimes = nil
	sVar.hasCostBattleTimes = nil
end

function getHeroConfigByHeroId(heroId)
	for idx, config in ipairs(NewHeroConfig.HeroList) do
		if config and config.heroId == heroId then
			return config
		end
	end
end

--[[激活英雄
扣元宝的战神，不允许在跨服战场激活
]]
function ActivateHero( sysarg, heroId )
	--print("ActivateHero, heroIdx="..heroIdx)
	if Actor.hasMapAreaAttri( sysarg, aaNotCallZhanJiang ) then  			--该区域禁止召唤战将
  		Actor.sendTipmsg( sysarg, Lang.ScriptTips.Hero009, ttFlyTip )
   		return
   	end

	local heroCfg = getHeroConfigByHeroId(heroId)
	if not heroCfg then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero001,ttFlyTip)
		return
	end

	local heroState = Hero.getHeroState( sysarg, heroCfg.heroId )
	if heroState ~= gHeroStateUnActive then				--已经激活了
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero003,ttFlyTip)
		return
	end

	if not CheckActivateHeroCond( sysarg, heroCfg ) then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero002,ttFlyTip)
		return
	end

	local heroId = heroCfg.heroId
	--print("ActivateHero, heroId="..heroId)

	local ret = Hero.addHero(sysarg, heroCfg.heroId)
	if ret and ret == heroCfg.heroId then
		--Hero.AutoLearnAllSkill(sysarg, heroCfg.heroId)
	end
end

--[[
检查激活英雄的条件
]]
function CheckActivateHeroCond( sysarg, heroCfg )
	if not heroCfg then
		return false
	end
	if not heroCfg.activateCond then
		return true
	end
	if #heroCfg.activateCond == 0 then
		return true
	end
	for i, cond in ipairs( heroCfg.activateCond ) do
		if CheckActivateHeroOneCond( sysarg, cond ) then
			return true
		end
	end
	return false
end

--[[
激活英雄的条件
]]
function CheckActivateHeroOneCond( sysarg, conds )
	for i, cond in ipairs( conds ) do
		if not CheckActivateHeroOneCondImp( sysarg, cond ) then
			return false
		end
	end
	return true
end

function CheckActivateHeroOneCondImp( sysarg, cond )
	if cond.level then				--等级要求
		if Actor.checkActorLevel( sysarg, cond.level, 0 ) then
			return true
		end
		return false
	elseif cond.openDay then
		local days = System.getDaysSinceOpenServer()
		if days >= cond.openDay then
			return true
		end
		return false
	elseif cond.hasHeroId then
		local heroState = Hero.getHeroState( sysarg, cond.hasHeroId )
		if heroState ~= gHeroStateUnActive then				--已经激活了
			return true
		end
		return false
	elseif cond.vipGrade then		--vip等级要求
		if Actor.getVipGrade( sysarg ) >= cond.vipGrade then
			return true
		end
		return false
	elseif cond.loginDay then		--登陆天数要求
		local loginDays = Actor.getLoginDays(sysarg)
		if loginDays >= cond.loginDay then
			return true
		end
		return false
	elseif cond.yuanBao then		--需要元宝
		if Actor.IsCross( sysarg ) then
			Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero011,ttFlyTip)
			return false
		end

		local myYuanBao = Actor.getMoneyCount(sysarg, mtYuanbao)
		if myYuanBao < cond.yuanBao then
			return false
		end

		if not Actor.delMoney( sysarg, mtYuanbao, cond.yuanBao, GameLog.clHeroActivateFee, Lang.ScriptTips.HeroLog001 ) then
			return false
		end
		return true
	end
	return false
end

function SetHeroState( sysarg, heroId, newState )
	--print("SetHeroState, heroIdx="..heroIdx..", newState="..newState)
	local heroCfg = getHeroConfigByHeroId(heroId)
	if not heroCfg then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero004, ttFlyTip)
		return
	end

	
	local heroState = Hero.getHeroState( sysarg, heroCfg.heroId )
	if heroState == gHeroStateUnActive then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero005, ttFlyTip)
		return
	elseif newState == heroState and  heroState == gHeroStateBattle then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero006, ttFlyTip)
		return
	
	elseif newState == heroState and  heroState == gHeroStateSleep then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.Hero007, ttFlyTip)
		return
	end

	if newState == gHeroStateBattle then
		if Actor.hasMapAreaAttri( sysarg, aaNotCallZhanJiang ) then 	  			--该区域禁止召唤战将
  			Actor.sendTipmsg( sysarg, Lang.ScriptTips.Hero010, ttFlyTip )
   			return
   		end

   		
		local sVar = Actor.getStaticVar(sysarg)
		local hasBattleTimes 	= sVar.heroBattleTimes or 0
		local hasCostBattleTimes 	= sVar.hasCostBattleTimes or 0
		local dailyBattleLimit 	= GetDailyHeroBattleLimit( sysarg )
		--print("GetTodayHeroBattleLimit, hasBattleTimes="..hasBattleTimes..", dailyBattleLimit="..dailyBattleLimit)
		--print("dailyBattleLimit=" ..dailyBattleLimit)
		--print("hasBattleTimes=" ..hasBattleTimes)
		if hasBattleTimes >= dailyBattleLimit then
			local costMoney = NewHeroConfig.firstCostMoney + hasCostBattleTimes * NewHeroConfig.addPreCostMoney
			if Actor.getMoneyCount(sysarg, mtYuanbao) < costMoney then
		      	Actor.sendItemLack( sysarg, qatYuanbao, 0, costMoney )
		      	return
		   	end

		   	if not Actor.delMoney( sysarg,mtYuanbao,costMoney,LogIds.HeroReliveComsumeLogId,Lang.LogTips.HeroReliveComsume) then
		      	return
		   	end
		   	sVar.hasCostBattleTimes = hasCostBattleTimes + 1
		else
			sVar.heroBattleTimes = hasBattleTimes + 1
		end
		SendDailyHeroBattleCount(sysarg)
		Hero.setHeroState( sysarg, heroCfg.heroId, newState )

		CheckHeroBattleCount(sysarg)
	else
		Hero.setHeroState( sysarg, heroCfg.heroId, newState )
		CheckHeroBattleCount(sysarg)
	end
end

--[[
--获取每日英雄出战次数（根据在线时间）
function GetDailyHeroBattleLimit( sysarg )
	local todaylineTime = Actor.getTodayOnlineTime(sysarg)		--今日累积在线时间(秒)
	local totallineTime = Actor.getTotalOnlineTime(sysarg)		--总累积在线时间(秒)
	local vipAddTimes = GetVipGradePrivValue( sysarg, enVipPriv_HeroSetBattle, 0 ) or 0
	--print("GetTodayHeroBattleLimit, todaylineTime="..todaylineTime..", totallineTime="..totallineTime..", vipAddTimes="..vipAddTimes)

	local allLimit = 0
	allLimit = vipAddTimes			--VIP加成的次数
	local count = #NewHeroConfig.dailyHeroBattleLimit
	for idx=1, count do
		local limitCfg = NewHeroConfig.dailyHeroBattleLimit[idx]
		if todaylineTime >= limitCfg.minite*60 then
			allLimit = allLimit + limitCfg.battleLimit
		else
			return allLimit
		end
	end
	return allLimit
end
]]

--转身处理
function HeroCircleHandle( sysarg, heroId, circle, level)
	--print("heroId ="..heroId)
	--print("circle ="..circle)
	--print("level ="..level)
	local newCircle = circle + 1
	HeroCircleHandleImpl(sysarg, heroId, newCircle, level)
end


--转生条件检测
function CheckHeroCircleCondition(sysarg, config, circle, level)
	if level < config.reqLevel then
		Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.HeroCircle002, config.reqLevel), ttFlyTip)
		return false
	end	

	if config.consumes then
		if not CheckConsumeCond( sysarg, config.consumes, 1 ) then
			return false
		end
	end

	local nPlayerCircle = Actor.getIntProperty(sysarg, PROP_ACTOR_CIRCLE)

	if circle > nPlayerCircle then
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.HeroCircle004,ttFlyTip)
		return false
	end
	
	return true
end


function HeroCircleHandleImpl(sysarg, heroId, circle, level)
	local config = NewHeroConfig.HeroCircleConsumes[circle]
	if not config then
		System.trace("Can not find HeroCircleConsumes config, circle="..circle)
		Actor.sendTipmsg(sysarg,Lang.ScriptTips.HeroCircle001,ttFlyTip)
		return
	end
	
	--条件检测
	local bCheck = CheckHeroCircleCondition(sysarg, config, circle, level)
	if not bCheck then
		return
	end	
	
	if config.consumes then
		DoConsumeCond( sysarg, config.consumes, 1, LogIds.HeroCircleConsumeLogId, Lang.LogTips.HeroCircleConsume )
	end
	
	local newLevel = level - config.chgLevel
	--转生
	Hero.setHeroCircle(sysarg, heroId, circle, newLevel)
		
	local msg = string.format(Lang.ScriptTips.HeroCircle003, circle)
	Actor.sendTipmsg(sysarg, msg, ttFlyTip)
   
	Actor.triggerAchieveEvent(sysarg, 78, 2, circle)							--成就
	OnHeroCircleHandle(sysarg, circle)
end


function GetDailyHeroBattleLimit( sysarg )
	
	local vipAddTimes = GetVipGradePrivValue( sysarg, enVipPriv_HeroSetBattle, 0 ) or 0
	local vipConcAddTimes = Actor.getConcurrentVipPriv( sysarg, enConcVipPriv_HeroReliveNum )  or 0
	
	return NewHeroConfig.dailyBattleLimit + vipAddTimes + vipConcAddTimes
end

function SendDailyHeroBattleCount(sysarg)
	local netPack = DataPack.allocPacket(sysarg, enHeroSystemId, sHeroReliveCount) 
  	if not netPack then return end
  	local sVar = Actor.getStaticVar(sysarg)
  	local dVar = Actor.getDyanmicVar(sysarg)
	local hasBattleTimes 	= sVar.heroBattleTimes or 0
	local nowTime = System.getCurrMiniTime()
	local startTime = dVar.delayMsgHeroBattleCountAddStartTime or 0

	local leftTime = 0
	if startTime > 0 then
		leftTime = startTime + NewHeroConfig.dailyBattleAddTime - nowTime
	end

	local hasCostBattleTimes = sVar.hasCostBattleTimes or 0
	--print("hasCostBattleTimes ="..hasCostBattleTimes)
  	DataPack.writeByte(netPack, hasBattleTimes)
  	DataPack.writeByte(netPack, hasCostBattleTimes)
  	DataPack.writeInt(netPack, leftTime)

  	DataPack.flush(netPack)
end

function CheckHeroBattleCount(sysarg)
	local sVar = Actor.getStaticVar(sysarg)
	local dVar = Actor.getDyanmicVar(sysarg)
	local hasBattleTimes 	= sVar.heroBattleTimes or 0
	local dailyBattleLimit 	= GetDailyHeroBattleLimit( sysarg )
	local heroState = Hero.getHeroState( sysarg, -1 )

	if hasBattleTimes >= dailyBattleLimit and heroState == gHeroStateSleep then
		local oldMsg = dVar.delayMsgHeroBattleCountAddStartTime
		if not oldMsg then	
			dVar.delayMsgHeroBattleCountAddStartTime = System.getCurrMiniTime()
			Actor.removeEntityScriptDelayMsg(sysarg, DELAY_MSG_HERO_RELIVE_TIME)
			Actor.postEntityScriptDelayMsg(sysarg, NewHeroConfig.dailyBattleAddTime*1000 ,result,DELAY_MSG_HERO_RELIVE_TIME,0,0,0,0, false, true)
			SendDailyHeroBattleCount(sysarg)
		end
	elseif heroState == gHeroStateBattle then
		dVar.delayMsgHeroBattleCountAddStartTime = nil
		Actor.removeEntityScriptDelayMsg(sysarg, DELAY_MSG_HERO_RELIVE_TIME)
		SendDailyHeroBattleCount(sysarg)
	end
end
function OnHeroBattleCountAdd(sysarg)
	local sVar = Actor.getStaticVar(sysarg)
	local dVar = Actor.getDyanmicVar(sysarg)
	Actor.removeEntityScriptDelayMsg(sysarg, DELAY_MSG_HERO_RELIVE_TIME)
	dVar.delayMsgHeroBattleCountAddStartTime = nil
	local hasBattleTimes 	= sVar.heroBattleTimes or 0
	local dailyBattleLimit 	= GetDailyHeroBattleLimit( sysarg )
	if hasBattleTimes > 0 then
		sVar.heroBattleTimes = hasBattleTimes - 1
	end
	CheckHeroBattleCount(sysarg)
	SendDailyHeroBattleCount(sysarg)
end

--[[
function SendHeroCircleLastLevel(sysarg, heroId, level, heroExp)
	--print("heroId ="..heroId)
	--print("heroExp ="..heroExp)
	local nMaxPlayerLevel = level

	local currExp = heroExp
	local toLevel = -1
	for idx = 1, nMaxPlayerLevel do
		if currExp < LevelUpExp[idx] then
			toLevel = idx - 1
			break
		else
			currExp = currExp - LevelUpExp[idx]
		end
	end
	if toLevel == -1 then
		toLevel = nMaxPlayerLevel
	end 
	--print("toLevel ="..toLevel)
	--print("sHeroCircleLevel ="..sHeroCircleLevel)
	local netPack = DataPack.allocPacket(sysarg, enHeroSystemId, sHeroCircleLevel)
	DataPack.writeWord(netPack, heroId)	
	DataPack.writeByte(netPack, toLevel)	
	DataPack.flush(netPack)
end
]]

function GmHeroClearReliveCount(sysarg)
  	local sVar = Actor.getStaticVar(sysarg)
	local dailyBattleLimit 	= GetDailyHeroBattleLimit( sysarg )
	sVar.heroBattleTimes = dailyBattleLimit
	SendDailyHeroBattleCount(sysarg)
end

function CheckHeroCircleSoulExchange(sysarg,config, level, circle)
	if level < config.reqLevel then
		Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.HeroCircle007, config.reqLevel), ttFlyTip)
		return false
	end
	

	local var = Actor.getStaticVar(sysarg)
	if not var.days then var.days = {} end	
	local useCircle = var.days.useHeroCircle
	if useCircle ~= nil and useCircle >=  NewHeroConfig.dailyCountLimit[circle + 1] then
		-- 当天的转数已经用完
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.HeroCircle008, ttFlyTip)
		return false
	end

	if not CheckConsumeCond( sysarg, config.consumes, 1 ) then
		--Actor.sendTipmsg(sysarg, Lang.ScriptTips.coin00001, ttFlyTip)
		return false
	end

	
	return true
end

function SendHeroLeftCircle(sysarg, useCircle)
	if useCircle == nil then
		local var = Actor.getStaticVar(sysarg)
		if not var.days then var.days = {} end
		useCircle = var.days.useHeroCircle
		if useCircle == nil then
			useCircle = 0 -- 默认是3次
		end
	end
	
	-- 下发今天剩余转生次数(已经改为今天兑换修为剩余次数)
	local netPack = DataPack.allocPacket(sysarg, 44, 9)
	DataPack.writeByte(netPack, useCircle)	
	DataPack.flush(netPack)
end


function SendHeroCircleExchangeLastCount(sysarg)
	SendHeroLeftCircle(sysarg, nil)
end

function SendHeroCircleExchange(sysarg, heroId, level, circle)
	local config = NewHeroConfig.HeroCircleSoulExchange[level - NewHeroConfig.activeLevel]
	if not config then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.HeroCircle006, ttFlyTip)
		System.trace("Can not find HeroCircleSoulExchange config,heroLevel="..level)
		return 1
	end

	local bCheck = CheckHeroCircleSoulExchange(sysarg,config,level, circle)
	if bCheck ~= true then return end 
	

	if not DoConsumeCond( sysarg, config.consumes, 1, 968, Lang.LogTips.l00186 ) then
		return
	end

	local var = Actor.getStaticVar(sysarg)
	if not var.days then var.days = {} end
	local useCircle = var.days.useHeroCircle
	if useCircle == nil then -- 今天剩余的转数(默认是3次)
		useCircle = 1		
	else
		useCircle = useCircle + 1
	end
	var.days.useHeroCircle = useCircle
		
	local currentSoul = Actor.getIntProperty(sysarg,PROP_ACTOR_HERO_CIRCLE_SOUL)
	Actor.setIntProperty(sysarg,PROP_ACTOR_HERO_CIRCLE_SOUL,currentSoul + config.addSoul)
	Hero.setHeroLevel(sysarg, heroId, config.chgLevel)
	Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.HeroCircle005, config.addSoul, currentSoul + config.addSoul), ttFlyTip)
	
	-- 下发今天剩余转生次数(已经改为今天兑换修为剩余次数)
	SendHeroLeftCircle(sysarg, useCircle)
end

function OnHeroCommonLogin(sysarg)
   Hero.sendHeroAllProperty(sysarg)
   CheckHeroBattleCount(sysarg)
end

function HeroSwitchState(sysarg, nState)
	nState = tonumber(nState)--test
	local nOldState =  Hero.getHeroProperty(sysarg, -1, enHeroPropFightState)
	if nOldState == nState then
		return
	end
	if nState ~= enfs_Attack and nState ~= enfs_ResistMon then
		return
	end
	local dVar = Actor.getDyanmicVar(sysarg)
	local cdTime = dVar.heroSwitchStateTime or 0 
	local nowTime = System.getCurrMiniTime()
	if cdTime > nowTime then
		Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.HeroState001,cdTime -nowTime), ttFlyTip)
		return
	end
	dVar.heroSwitchStateTime = nowTime + NewHeroConfig.switchStateCd
	Hero.setHeroProperty(sysarg, -1, enHeroPropFightState, nState)
end



registerScriptCallBack(DELAY_MSG_HERO_RELIVE_TIME, OnHeroBattleCountAdd)
EventCallDispatcher.registerEventCall(aeHeroDeath, CheckHeroBattleCount)